﻿package ua.mihaylenko.cardsplugin.colorpicker{
	/**
	Its a vertical slider class to select different color(hue) with dragging the 
	slider. It interacts with ColorPickerCanvas, which displays saturation of selected hue
	
	@author Sharwan Kami <sharwan@gmail.com>
	@version 1.0
	@history 2009-05-10
	
	* 
	* This file is part of E-Card plugin, from zetaprints.com
	* 
	
	@usage
	Activate with:
		<code>
			//initialize the Color Slider Class
			colorSlider=new ColorSlider();
			colorSlider.color=0x0000ff;
			colorSlider.x=216;
			colorSlider.y=30;
			addChild(colorSlider);
		</code>
	
	*/
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.display.GradientType;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.geom.Rectangle;
	
	public class ColorSlider extends Sprite{
		public var bd:BitmapData;
		public var bm:Bitmap;
		
		private var fillTypeC:String = GradientType.LINEAR;
		private var colorsC:Array = [0xFF0000,0xFFFF00,0x00FF00,0x00FFFF,0x0000FF, 0xFF00FF,0xFF0000 ];
		private var alphasC:Array = [1,     1,     1,     1,     1,      1,     1];
		private var ratiosC:Array = [0,       42,      64,       127,    184,      215,     255];
		private var matrixC:Matrix= new Matrix();
		
		private var w=35;//width
		private var h=200;//height
		
		private var activeColor:uint;		
		
		public var colorSlider;
		
		/**
			Constructor
			*	Create the gradient box 
			*	Create the slider
			*	Add event listeners for slider
		*/
		function ColorSlider(){
			drawColor();
			
			colorSlider=new CSlider();
			addChild(colorSlider);
			
			addEventListener(MouseEvent.MOUSE_DOWN,onSliderDown);
			addEventListener(MouseEvent.MOUSE_UP,onSliderUp);			
		}
		
		/**
		Updates the position of the slider based on the color passed
		*/		
		public function setSliderPosition(c:uint):void{
			var steps:uint = 0;
			var rect:Rectangle;
			var r:uint;
			var g:uint;
			var b:uint;
			do{
				rect = bd.getColorBoundsRect(0xFFFFFFFF, 0xFF000000+c, true);
				steps++;
				
				r = c >> 16 & 0xff
				g = c >> 8 & 0xff
				b = c & 0xff;
				r = Math.min(r+1, 255);
				g = Math.min(g+1, 255);
				b = Math.min(b+1, 255);
				
				c = r << 16 | g << 8 | b
			}while(rect.width == 0 && c > 0 && steps < 7000);
			
			colorSlider.y = rect.bottom;
		}
		
		/**
			Draws the gradient box with selected colors
		*/
		public function drawColor():void{
			matrixC.createGradientBox(35,200,90*Math.PI/180);
			var mc=new Sprite();
			mc.graphics.beginGradientFill(fillTypeC,colorsC,alphasC,ratiosC,matrixC);
			mc.graphics.drawRect(0,0,w,h+1);
			mc.graphics.endFill();	
			
			bd = new BitmapData(mc.width,mc.height);
			bd.draw(mc);	
			bm = new Bitmap(bd);
			addChild(bm);
		}
		
		/**
		event listener to fire on mousedown of the color slider
		*/
		function onSliderDown(e:MouseEvent):void{
			var rect:Rectangle=new Rectangle(0,0,0,h);
			colorSlider.startDrag(true,rect);
			
			//following event listener is added to its parent to catch mouseup outside the color slider
			this.parent.parent.addEventListener(MouseEvent.MOUSE_UP,onStageMouseUp);
			colorSlider.addEventListener(Event.ENTER_FRAME,onSliderEnterFrame);
		}
		
		/**
		this updates the color based on sliders vertical(y) position,
		keeping the x position on the center,
		also it dispatches the event to notify color change
		*/
		function onSliderEnterFrame(e):void{
			activeColor=bd.getPixel(width*.5,colorSlider.y);
			dispatchEvent(new Event("colorChanged"));
		}
		
		function onStageMouseUp(e):void{
			if(e.target!=this){
				colorSlider.stopDrag();
				colorSlider.removeEventListener(Event.ENTER_FRAME,onSliderEnterFrame);
			}			
			this.parent.parent.removeEventListener(MouseEvent.MOUSE_UP,onStageMouseUp);
		}
		
		function onSliderUp(e:MouseEvent):void{
			colorSlider.removeEventListener(Event.ENTER_FRAME,onSliderEnterFrame);
			colorSlider.stopDrag();			
		}
		
		/**
		returns the selected color
		*/
		public function get color():uint{
			return activeColor;
		}
		
		/**
		sets the new color
		*/
		public function set color(val:uint):void{
			activeColor=val;
			dispatchEvent(new Event("colorChanged"));
		}
	}
}